Computing movement speed¶

Binder IPYNB HTML

MovingPandas offers functions to compute and/or visualize the speed of movement along the trajectory between consecutive points.

In [1]:
import pandas as pd
import geopandas as gpd
import movingpandas as mpd
import shapely as shp
import hvplot.pandas 

from geopandas import GeoDataFrame, read_file
from shapely.geometry import Point, LineString, Polygon
from datetime import datetime, timedelta
from holoviews import opts

import warnings
warnings.filterwarnings('ignore')

opts.defaults(opts.Overlay(active_tools=['wheel_zoom'], frame_width=500, frame_height=400))

mpd.show_versions()
MovingPandas 0.10.rc1

SYSTEM INFO
-----------
python     : 3.9.13 | packaged by conda-forge | (main, May 27 2022, 16:50:36) [MSC v.1929 64 bit (AMD64)]
executable : H:\miniconda3\envs\mpd-ex\python.exe
machine    : Windows-10-10.0.19043-SP0

GEOS, GDAL, PROJ INFO
---------------------
GEOS       : None
GEOS lib   : None
GDAL       : 3.5.0
GDAL data dir: None
PROJ       : 9.0.0
PROJ data dir: H:\miniconda3\pkgs\proj-9.0.0-h1cfcee9_1\Library\share\proj

PYTHON DEPENDENCIES
-------------------
geopandas  : 0.10.2
pandas     : 1.4.2
fiona      : 1.8.21
numpy      : 1.22.4
shapely    : 1.8.2
rtree      : 1.0.0
pyproj     : 3.3.1
matplotlib : 3.5.2
mapclassify: 2.4.3
geopy      : 2.2.0
holoviews  : 1.14.9
hvplot     : 0.8.0
geoviews   : 1.9.5
stonesoup  : 0.1b9

Basic example¶

In [2]:
df = pd.DataFrame([
  {'geometry':Point(0,0), 't':datetime(2018,1,1,12,0,0)},
  {'geometry':Point(6,0), 't':datetime(2018,1,1,12,0,6)},
  {'geometry':Point(6,6), 't':datetime(2018,1,1,12,0,11)},
  {'geometry':Point(9,9), 't':datetime(2018,1,1,12,0,14)}
]).set_index('t')
gdf = GeoDataFrame(df, crs=31256)
toy_traj = mpd.Trajectory(gdf, 1)
toy_traj
Out[2]:
Trajectory 1 (2018-01-01 12:00:00 to 2018-01-01 12:00:14) | Size: 4 | Length: 16.2m
Bounds: (0.0, 0.0, 9.0, 9.0)
LINESTRING (0 0, 6 0, 6 6, 9 9)
In [3]:
help(mpd.Trajectory.add_speed)
Help on function add_speed in module movingpandas.trajectory:

add_speed(self, overwrite=False, name='speed')
    Add speed column and values to the trajectory's DataFrame.
    
    Speed is calculated as CRS units per second, except if the CRS is
    geographic (e.g. EPSG:4326 WGS84) then speed is calculated in meters
    per second.
    
    Parameters
    ----------
    overwrite : bool
        Whether to overwrite existing speed values (default: False)
    name : str
        Name of the speed column (default: "speed")

In [4]:
toy_traj.add_speed(overwrite=True)
toy_traj.df
Out[4]:
geometry speed
t
2018-01-01 12:00:00 POINT (0.000 0.000) 1.000000
2018-01-01 12:00:06 POINT (6.000 0.000) 1.000000
2018-01-01 12:00:11 POINT (6.000 6.000) 1.200000
2018-01-01 12:00:14 POINT (9.000 9.000) 1.414214

We can also visualize the speed values:

In [5]:
toy_traj.plot(column="speed", linewidth=5, capstyle='round', legend=True)
Out[5]:
<AxesSubplot:>

Real-world trajectories¶

In [6]:
gdf = read_file('../data/geolife_small.gpkg')
traj_collection = mpd.TrajectoryCollection(gdf, 'trajectory_id', t='t')
In [7]:
my_traj = traj_collection.trajectories[1]
In [8]:
my_traj.df
Out[8]:
id sequence trajectory_id tracker geometry
t
2009-06-29 07:02:25 1556 1090 2 0 POINT (116.59096 40.07196)
2009-06-29 07:02:30 1557 1091 2 0 POINT (116.59091 40.07201)
2009-06-29 07:02:35 1558 1092 2 0 POINT (116.59088 40.07203)
2009-06-29 07:02:40 1559 1093 2 0 POINT (116.59091 40.07200)
2009-06-29 07:02:45 1560 1094 2 0 POINT (116.59096 40.07198)
... ... ... ... ... ...
2009-06-29 11:09:47 2448 1982 2 0 POINT (116.32349 40.00037)
2009-06-29 11:09:57 2449 1983 2 0 POINT (116.32513 40.00057)
2009-06-29 11:10:02 2450 1984 2 0 POINT (116.32688 40.00087)
2009-06-29 11:10:07 2451 1985 2 0 POINT (116.32722 40.00101)
2009-06-29 11:13:12 2452 1986 2 0 POINT (116.32746 40.00052)

897 rows × 5 columns

Even if the GeoDataFrame does not contain a speed column, we can still plot movement speed:

In [9]:
my_traj.plot(column='speed', linewidth=5, capstyle='round', figsize=(9,3), legend=True, vmax=20)
Out[9]:
<AxesSubplot:>
In [10]:
my_traj.hvplot(c='speed', clim=(0,20), line_width=7.0, tiles='CartoLight', cmap='Viridis', colorbar=True)
Out[10]:
In [11]:
traj_collection.plot(column='speed', linewidth=5, capstyle='round', legend=True, vmax=20)
Out[11]:
<AxesSubplot:>
In [ ]: